#include "stdafx.h"
#include <windows.h>
#include <time.h>
#include "LogFile.h"

using namespace std;
namespace Zen{namespace utility{

LogFile::LogFile(const char *fileName)
: m_fileName(NULL)
{
	setFileName(fileName);
}

LogFile::~LogFile()
{
	close();

	if (NULL != m_fileName) {
		delete [] m_fileName;
		m_fileName = NULL;
	}
}

bool LogFile::open(const char *fileName)
{
	if (isOpen())
		return true;

	if (NULL != fileName)
		setFileName(fileName);
	
    if (NULL == m_fileName)
		return false;

	m_fileStream.open(m_fileName, ios::in | ios::out | ios::app);
    m_fileStream.seekp(0, ios::end);

    return m_fileStream.good();
}

void LogFile::close()
{
	if (isOpen()) {
		m_fileStream.flush();
		m_fileStream.close();
	}
}

void LogFile::flush()
{
	m_fileStream.flush();
}

int LogFile::size()
{
	return m_fileStream.tellg();
}

bool LogFile::isOpen() const
{
	return m_fileStream.is_open();
}

const char * LogFile::fileName() const
{
	return m_fileName;
}

void LogFile::setFileName(const char *fileName)
{
	if (NULL != m_fileName) {
		delete [] m_fileName;
		m_fileName = NULL;
	}

	if (NULL == fileName)
		return;

	size_t len = strlen(fileName) + 1;
	m_fileName = new char[len];
	if (NULL != m_fileName) {
		memset((void *)m_fileName, 0, len);
		memcpy((void *)m_fileName, fileName, len);
	}
}

int LogFile::write(const char * buffer, int length)
{
	if (!isOpen())
		return -1;

	m_fileStream.write(buffer, length);
	return length; // FIXME: it is not safe!
}

int LogFile::log(const char *fmt, ...)
{
	if (!isOpen())
		return -1;

    char str[MaxLogSize];
	int size;

    va_list args;
    va_start(args, fmt);
    size = _vsnprintf_s(str, sizeof(str), fmt, args);
	va_end(args);

	time_t now;
    char temp[24];

	time(&now);
	strftime(temp, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
	m_fileStream << temp << " ";
	m_fileStream << str << std::endl;
	m_fileStream.flush();

	return size; // FIXME: we may need to check the write size!
}

int LogFile::LogEx(const char *fileName, const char *fmt, ...)
{
	if (NULL == fileName)
		return -1;

	LogFile file(fileName);
	if (file.open())
		return -1;

	char str[MaxLogSize];
	int size;

    va_list args;
    va_start(args, fmt);
	size = _vsnprintf_s(str, sizeof(str), fmt, args);
	va_end(args);

	file.log(str);
	file.close();

	return size;
}

}}